﻿using System;
using System.Collections.Generic;

namespace Smart.CE.Log
{
    /// <summary>
    /// 
    /// </summary>
    public static class Log
    {
        private static LogLevel logLevel = LogLevel.Off;
        private static List<LogListener> listeners = new List<LogListener>();
        private static bool autoFlush = true;
        private static int indentLevel;
        private static int indentSize;

        /// <summary>
        /// 
        /// </summary>
        public static LogLevel LogLevel
        {
            get
            {
                return logLevel;
            }
            set
            {
                logLevel = value;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public static List<LogListener> Listeners
        {
            get
            {
                return listeners;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public static bool AutoFlush
        {
            get
            {
                return autoFlush;
            }
            set
            {
                autoFlush = value;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public static int IndentSize
        {
            get
            {
                return indentSize;
            }
            set
            {
                SetIndentSize( value );
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public static int IndentLevel
        {
            get
            {
                return indentLevel;
            }
            set
            {
                SetIndentLevel( value );
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public static void Close()
        {
            if( listeners != null )
            {
                foreach( LogListener listener in listeners )
                {
                    listener.Close();
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public static void Flush()
        {
            if( listeners != null )
            {
                foreach( LogListener listener in listeners )
                {
                    listener.Flush();
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public static void Indent()
        {
            indentLevel++;
            foreach( LogListener listener in listeners )
            {
                listener.IndentLevel = indentLevel;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public static void Unindent()
        {
            if( indentLevel > 0 )
            {
                indentLevel--;
            }

            foreach( LogListener listener in listeners )
            {
                listener.IndentLevel = indentLevel;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="value"></param>
        private static void SetIndentLevel(int value)
        {
            if( value < 0 )
            {
                value = 0;
            }
            indentLevel = value;

            foreach( LogListener listener in listeners )
            {
                listener.IndentLevel = indentLevel;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="value"></param>
        private static void SetIndentSize(int value)
        {
            if( value < 0 )
            {
                value = 0;
            }
            indentSize = value;

            foreach( LogListener listener in listeners )
            {
                listener.IndentSize = indentSize;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="message"></param>
        public static void Write(string message)
        {
            foreach( LogListener listener in listeners )
            {
                listener.Write( message );
                if( autoFlush )
                {
                    listener.Flush();
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="value"></param>
        public static void Write(object value)
        {
            foreach( LogListener listener in listeners )
            {
                listener.Write( value );
                if( autoFlush )
                {
                    listener.Flush();
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="message"></param>
        public static void WriteLine(string message)
        {
            foreach( LogListener listener in listeners )
            {
                listener.WriteLine( message );
                if( autoFlush )
                {
                    listener.Flush();
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="value"></param>
        public static void WriteLine(object value)
        {
            foreach( LogListener listener in listeners )
            {
                listener.WriteLine( value );
                if( autoFlush )
                {
                    listener.Flush();
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="condition"></param>
        /// <param name="message"></param>
        public static void WriteIf(bool condition, string message)
        {
            if( condition )
            {
                Write( message );
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="condition"></param>
        /// <param name="value"></param>
        public static void WriteIf(bool condition, object value)
        {
            if( condition )
            {
                Write( value );
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="condition"></param>
        /// <param name="message"></param>
        public static void WriteLineIf(bool condition, string message)
        {
            if( condition )
            {
                WriteLine( message );
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="condition"></param>
        /// <param name="value"></param>
        public static void WriteLineIf(bool condition, object value)
        {
            if (condition)
            {
                WriteLine(value);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="message"></param>
        public static void Error(string message)
        {
            if( logLevel >= LogLevel.Error )
            {
                WriteLine( message );
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="value"></param>
        public static void Error(object value)
        {
            if( logLevel >= LogLevel.Error )
            {
                WriteLine( value );
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="message"></param>
        public static void Warning(string message)
        {
            if( logLevel >= LogLevel.Warning )
            {
                WriteLine( message );
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="value"></param>
        public static void Warning(object value)
        {
            if( logLevel >= LogLevel.Warning )
            {
                WriteLine( value );
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="message"></param>
        public static void Info(string message)
        {
            if( logLevel >= LogLevel.Info )
            {
                WriteLine( message );
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="value"></param>
        public static void Info(object value)
        {
            if( logLevel >= LogLevel.Info )
            {
                WriteLine( value );
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="message"></param>
        public static void Debug(string message)
        {
            if( logLevel >= LogLevel.Debug )  
            {
                WriteLine( message );                
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="value"></param>
        public static void Debug(object value)
        {
            if( logLevel >= LogLevel.Debug )
            {
                WriteLine( value );
            }
        }
    }
}
